#define _CRT_NON_CONFORMING_SWPRINTFS
#include "libutilsconfig.h"
#include <stdarg.h>
#include "tStringBuilder.h"

LIB_NS_BEGIN

static const int DEFAULT_BUFF_LEN = 512;
TStringBuilder::TStringBuilder(size_t capi)
{
	_init(capi);
}

void TStringBuilder::_init(int32 cap)
{
	_bufflen = cap;
	_buff = new TCHAR[_bufflen+1];
	_pos = 0;
	_buff[_pos]=0;
	_ownbuff = true;
}

TStringBuilder::TStringBuilder()
{
	_init(DEFAULT_BUFF_LEN);
}

TStringBuilder::TStringBuilder( void* buff,int len)
{
	_buff = (TCHAR*)buff;
	_pos = 0;
	_bufflen = len;

	_ownbuff = false;
}

TStringBuilder::~TStringBuilder(void)
{
	if(_ownbuff)
	{
		delete[] _buff;
	}
	
}

void TStringBuilder::_resize(int32 newlen)
{
	
	TCHAR* newbuff = new TCHAR[newlen+1];
	_tcscpy(newbuff,_buff);
	delete[] _buff;
	_buff = newbuff;
	_bufflen = newlen;
}

TStringBuilder& TStringBuilder::Append( TCHAR value )
{
	TCHAR data[2] = {value,0};
	Append(data);
	return *this;
}

TStringBuilder& TStringBuilder::Append( const TCHAR* value )
{
	int32 len = _tcslen(value);
	if(len+_pos <= _bufflen)
	{
		_tcscat(_buff,value);
		_pos += len;
	}
	else
	{
		int newlen = (len + _pos)*2;
		_resize(newlen*sizeof(TCHAR));
		Append(value);
	}
	return *this;
}

TStringBuilder& TStringBuilder::Append( const tstring& value )
{
	return Append(value.c_str());
}

void TStringBuilder::_appendend()
{
	_buff[_pos]=0;
}

tstring TStringBuilder::ToString()
{
	return _buff;
}

TStringBuilder& TStringBuilder::AppendFormat( const TCHAR* fmt,... )
{
	TCHAR tmp[1024] = {0};
	va_list pArg;
	va_start(pArg, fmt);
	_vstprintf(tmp, fmt, pArg);
	va_end(pArg);
	return Append(tmp);

	/*
	va_list pArg;
	va_start(pArg, fmt);
	_vstprintf(&_buff[_pos], fmt, pArg);
	va_end(pArg);
	
	_pos += _tcslen(&_buff[_pos]);
	_buff[_pos] = 0;
	
	return *this;
	*/
}

tstring TStringBuilder::Format( const TCHAR* fmt )
{
	TCHAR buff[1024*8] = {0};
	TStringBuilder cb(buff);
	cb.AppendFormat(fmt);
	return buff;
}

TCHAR* TStringBuilder::GetBuffer() const
{
	return _buff;
}

int TStringBuilder::GetIndex() const
{
	return _pos*sizeof(TCHAR);
}

LIB_NS_END